package com.ajieee.merge.service.impl;

import com.ajieee.merge.entity.finance.Quote;
import com.ajieee.merge.entity.finance.dto.SelfChosenReqDTO;
import com.ajieee.merge.entity.finance.dto.SelfChosenRespDTO;
import com.ajieee.merge.entity.finance.po.SelfChosenPO;
import com.ajieee.merge.enums.finance.ChosenType;
import com.ajieee.merge.mapper.EtfQuoteMapper;
import com.ajieee.merge.mapper.SelfChosenMapper;
import com.ajieee.merge.mapper.StockQuoteMapper;
import com.ajieee.merge.service.SelfChosenService;
import com.ajieee.merge.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author ajieee
 * @date 2025-10-31
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SelfChosenServiceImpl implements SelfChosenService {

	private final SelfChosenMapper selfChosenMapper;

	private final EtfQuoteMapper etfQuoteMapper;

	private final StockQuoteMapper stockQuoteMapper;

	@Override
	public List<SelfChosenRespDTO> list(SelfChosenReqDTO dto) {
		boolean searchValue = StringUtils.isNotBlank(dto.getSearchValue());
		Wrapper<SelfChosenPO> wrapper = Wrappers.<SelfChosenPO>lambdaQuery()
				.eq(SelfChosenPO::getUserId, 1L)
				.eq(SelfChosenPO::getType, dto.getChosenType())
				.and(searchValue, wra ->
						wra.like(SelfChosenPO::getTargetCode, dto.getSearchValue())
								.or()
								.like(SelfChosenPO::getTargetName, dto.getSearchValue())
				);
		List<SelfChosenPO> list = selfChosenMapper.selectList(wrapper);
		if (list.isEmpty()) {
			return List.of();
		}
		// 查询当前行情
		List<String> codes = list.stream().map(SelfChosenPO::getTargetCode).toList();
		List<? extends Quote> latestQuotes = getQuotes(codes, dto.getChosenType());
		Map<String, ? extends Quote> quoteMap = latestQuotes.stream()
				.collect(Collectors.toMap(Quote::getCode, Function.identity()));

		return list.stream().map(po -> {
			SelfChosenRespDTO respDTO = new SelfChosenRespDTO();
			BeanUtils.copyProperties(po, respDTO);
			if (quoteMap.containsKey(po.getTargetCode())) {
				Quote quote = quoteMap.get(po.getTargetCode());
				respDTO.setDataDate(quote.getDataDate());
				respDTO.setPrice(quote.getClose());
				respDTO.setChange(quote.getChange());
				respDTO.setChangeRatio(quote.getChangeRatio());
				double yield = (quote.getClose() - po.getChosenPrice()) / po.getChosenPrice() * 100;
				respDTO.setYield(yield);
			}
			return respDTO;
		}).toList();
	}

	private List<? extends Quote> getQuotes(List<String> codes, ChosenType chosenType) {
		return chosenType == ChosenType.ETF ?
				etfQuoteMapper.queryLatestQuotes(codes) :
				stockQuoteMapper.queryLatestQuotes(codes);
	}
}
